// 考虑整合到 plot.js 中
// 测试中
var data4DS = {
    '1000': {}, '100': {}, '10': {}, '1': {}
};
var data4N = [];
var positions = {};
var seqLen;
function deep_insight(sid, chr, pos, mbpCnt) {
    pos = parseInt(pos);
    var svgSettings = {
        colors: { bg: $('#bg-color').val(), fg: $('#fg-color').val() },
        fontSize: { label: 14, title: 20 },
        margin: { left: 60, right: 50, top: 150, bottom: 50 },
        // interval: e.g. g1000 和 g100 的间隔
        width: { chr: 30, max_bar: 50, gap: 5, interval: 80 },
        ids: {
            group: { '1000': 'g1000', '100': 'g100', '10': 'g10', '1': 'g1' }
        }
    }

    var jobId = $('#job-id').text();
    var current_pIqC = $('#current-pI').text() + '_' + $('#current-qC').text();
    var url_hsps = '/b2dsc/handle_ajax?jid=' + jobId + '&category=' +
        'hsps' + '&sid=' + sid + '&pIqC=' + current_pIqC +
        '&chr=' + chr + '&n=' + pos;
    $('a#hsp-coordinates').attr('href',
        url_hsps + '&task=coords'
    );
    $('a#hsp-coordinates').attr('target', '_blank');

    $.getJSON('/b2dsc/handle_ajax', {
        jid: jobId, category: 'done', keys: 'qseq_lens'
    }, function (done) {
        seqLen = done.qseq_lens[sid];
        // $.getJSON(url_hsps, function (data) {
        $.getJSON(url_hsps + '&getNs=1', function (data) {
            positions['1000'] = pos;
            data4DS['1000'] = data.hsps;
            data4N = data['N'];

            $('#deep-insight-svg').html('');
            $('#deep-insight').show();

            // var w = 150 * 2 + 200 * 3, h = 1200;
            var margins = svgSettings.margin, widths = svgSettings.width;
            var w = margins.left + margins.right + (widths.chr + widths.max_bar * 2 + widths.gap * 2) * 4 + widths.interval * 3,
                h = 1000 + margins.top + margins.bottom;
            var svg = d3.select('#deep-insight-svg').append('svg')
                .attr('width', w).attr('height', h)
                .attr('xmlns', 'http://www.w3.org/2000/svg')
                .attr('xmlns:xlink', 'http://www.w3.org/1999/xlink')
                .attr('version', '1.1');

            var zoom = d3.zoom().scaleExtent([0.1, 10]).on("zoom", zoomed);

            var bg = svg.append('rect').attr('width', w).attr('height', h)
                .attr('fill', svgSettings.colors.bg).attr('stroke', svgSettings.colors.bg);
            var svgDefs = svg.append('defs');

            var container = svg.append('g').attr('class', 'container');

            add_defs(svgDefs);
            add_title(container, chr);
            add_legend(container);
            add_groups(container);
            plot_g1000();

            d3.select('#reset-deep-insight-svg').on("click", resetted);
            svg.call(zoom);

            function zoomed() {
                container.attr("transform", d3.event.transform);
            }

            function resetted() {
                svg.transition()
                    .duration(750)
                    .call(zoom.transform, d3.zoomIdentity);
            }
        });
    });

    function add_defs(svgDefs) {
        var gAxis = svgDefs.append('g').attr('id', 'dS-Axis');
        var dLines = [];
        dLines.push({ x1: 0, x2: 0, y1: 0, y2: 1000 });
        for (var i = 0; i <= 1e3; i++) {
            if (i % 100 === 0) {
                dLines.push({ x1: 0, x2: 6, y1: i, y2: i });
            } else if (i % 50 === 0) {
                dLines.push({ x1: 0, x2: 5, y1: i, y2: i });
            } else if (i % 10 === 0) {
                dLines.push({ x1: 0, x2: 3, y1: i, y2: i });
            }
        }
        gAxis.selectAll('line').data(dLines).enter().append('line')
            .attr('x1', function (d) { return d.x1 }).attr('y1', function (d) { return d.y1 })
            .attr('x2', function (d) { return d.x2 }).attr('y2', function (d) { return d.y2 }).attr('stroke', svgSettings.colors.fg);
    }

    function add_title(svg) {
        svg.append('text').attr('x', 10).attr('y', 10)
            .text(sid + ' (' + seqLen + ' bp) on ' + chr + ' (count: ' + mbpCnt + ')')
            .attr('font-family', svgFontFamily)
            .attr('font-size', svgSettings.fontSize.title)
            .attr('fill', svgSettings.colors.fg)
            .attr('dy', svgSettings.fontSize.title)
            .attr('font-weight', 'bold');
    }

    function add_legend(svg) {
        var fsize = svgSettings.fontSize.label;
        var xt = 600, yt = 10, wBox = 150, hBox = 30, wL = 20, hL = 20;
        var legend = svg.append('g').attr('transform', 'translate(' + xt + ', ' + yt + ')');
        var gRect = legend.append('g').attr('stroke', svgSettings.colors.fg),
            gText = legend.append('g').attr('fill', svgSettings.colors.fg);
        gRect.append('rect').attr('x', 0).attr('y', 0).attr('width', wBox).attr('height', hBox).attr('fill', svgSettings.colors.bg);
        var x = 10;
        gRect.append('rect').attr('x', x).attr('y', 5)
            .attr('width', wL).attr('height', hL).attr('fill', '#FF6666');
        x += wL + 10;
        gText.append('text').attr('x', x).attr('y', 5).attr('dy', fsize)
            .attr('font-family', svgFontFamily).attr('font-size', fsize)
            .text('plus');
        x += fsize + 20;
        gRect.append('rect').attr('x', x).attr('y', 5)
            .attr('width', wL).attr('height', hL).attr('fill', '#99CC66');
        x += wL + 10;
        gText.append('text').attr('x', x).attr('y', 5).attr('dy', fsize)
            .attr('font-family', svgFontFamily).attr('font-size', fsize)
            .text('minus');
    }

    function add_groups(svg) {
        // var xt = 150, yt = svgSettings.margin.top;
        var widths = svgSettings.width;
        var xt = svgSettings.margin.left + widths.max_bar + widths.gap + widths.chr / 2, yt = svgSettings.margin.top;
        for (var gunit = 1000; gunit >= 1; gunit /= 10) {
            svg.append('g').attr('id', svgSettings.ids.group[gunit])
                .attr('transform', 'translate(' + xt + ', ' + yt + ')');
            // xt += 200;
            xt += widths.chr + widths.max_bar * 2 + widths.interval + widths.gap * 2;
        }
    }

    function plot_g1000() {
        var gunit = 1000;
        var grp = d3.select('svg > g.container > g#' + svgSettings.ids.group['1000']);
        chr_and_bars(gunit, grp, data4DS['1000']);
    }

    function chr_and_bars(gunit, grp, data) {
        var eunit = gunit / 10; // each sect unit
        var colors = svgSettings.colors, fontSize = svgSettings.fontSize;
        var w_chr = svgSettings.width.chr,
            h_bar = 100, w_max_bar = svgSettings.width.max_bar,
            w_gap = svgSettings.width.gap;
        var max_cnt = 0;
        $.each(data, function (strand, dPos) { // data of each pos
            $.each(dPos, function (p, ses) { // se: start, end
                var len = ses.length;
                max_cnt = (len > max_cnt) ? len : max_cnt;
            });
        });
        var w_unit = w_max_bar / max_cnt;
        var y = 0, dRect = [], dText = [], w_bar, cnt = 0;
        for (var i = 0; i < 10; i++) {
            dText.push({
                x: 0, y: y,
                text: i + '', anchor: 'middle', fill: colors.fg
            });
            if (data.plus && data.plus[i]) {
                cnt = data.plus[i].length;
                w_bar = cnt * w_unit;
                dRect.push({
                    id: ['plus', eunit, i].join('-'),
                    w: w_bar, h: h_bar - 1,
                    x: w_chr / 2 + w_gap, y: y, fill: '#FF6666'
                });
                dText.push({
                    x: w_chr / 2 + w_gap * 2 + w_bar,
                    y: y + h_bar / 2,
                    text: cnt + '', anchor: 'start', fill: colors.fg
                });
            }
            if (data.minus && data.minus[i]) {
                cnt = data.minus[i].length;
                w_bar = cnt * w_unit;
                dRect.push({
                    id: ['minus', eunit, i].join('-'),
                    w: w_bar, h: h_bar - 1,
                    x: -(w_bar + w_chr / 2 + w_gap), y: y, fill: '#99CC66'
                });
                dText.push({
                    x: -(w_bar + w_chr / 2 + w_gap * 2),
                    y: y + h_bar / 2,
                    text: cnt + '', anchor: 'end', fill: colors.fg
                });
            }
            y += h_bar;
        }
        dText.push({
            x: 0, y: y,
            text: 10 + '', anchor: 'middle', fill: colors.fg
        });

        var rects = grp.selectAll('rect.clickable').data(dRect).enter().append('rect')
            .attr('id', function (d) { return d.id })
            .attr('class', 'clickable')
            .attr('width', function (d) { return d.w })
            .attr('height', function (d) { return d.h })
            .attr('x', function (d) { return d.x }).attr('y', function (d) { return d.y })
            .attr('fill', function (d) { return d.fill })
            .on('click', click_rect)
            .on('mouseover', mouseover_rect)
            .on('mouseout', mouseout_rect)
            ;
        grp.selectAll('text').data(dText).enter().append('text')
            .attr('x', function (d) { return d.x }).attr('y', function (d) { return d.y })
            .text(function (d) { return d.text }).attr('font-family', svgFontFamily)
            .attr('font-size', fontSize.label)
            .attr('fill', function (d) { return d.fill })
            .attr('text-anchor', function (d) { return d.anchor }).attr('dy', 5);

        var txt = grp.append('text').attr('x', 0).attr('y', -30)
            .attr('font-family', svgFontFamily)
            .attr('font-size', fontSize.label)
            .attr('fill', colors.fg).attr('font-weight', 'bold')
            .attr('text-anchor', 'middle');
        var prefix, pf1 = 0, pf2 = 0; // 实在是不会起名，概念模糊
        if (gunit < 1e3) {
            for (var u = 1e3; u > gunit; u /= 10) {
                pf1 += positions[u] * parseInt(u);
            }
            pf2 = pf1;
            pf1 += positions[gunit] * gunit;
            pf2 += (positions[gunit] + 1) * gunit;
            prefix = pf1 + '–' + pf2;
        } else {
            pf1 = positions[gunit], pf2 = pf1 + 1;
            prefix = pf1 + '–' + pf2;
        }
        var suffix = (gunit < 1e3) ? 'Kbp' : 'Mbp';
        txt.append('tspan').attr('x', 0).attr('dy', -fontSize.label).text(prefix + ' ' + suffix);
        txt.append('tspan').attr('x', 0).attr('dy', fontSize.label).text('Each: ' + eunit + ' Kbp');

        var gNs = grp.append('g').attr('class', 'nSegs')
            .attr('transform', 'translate(' + 0 + ', ' + 0 + ')');
        if (suffix === 'Mbp') {
            plotNs(gNs, pf1 * gunit * 1e3, pf2 * gunit * 1e3, 1 / gunit);
        } else if (suffix === 'Kbp') {
            plotNs(gNs, pf1 * 1e3, pf2 * 1e3, 1 / gunit);
        }
    }

    function mouseover_rect(event) {
        var threshold = 100; // 序列重复数阈值

        var event = event ? event : (window.event || d3.event);
        var rid = event.id; // rect id
        var thisRect = $('#' + rid);

        var pid = $('#' + rid).parent().attr('id');
        $('#' + pid + ' .clickable').removeClass('selectedRect');
        $('#' + rid).addClass('selectedRect');

        var type_unit_pos_cnt = rid.split('-');
        var eunit = parseInt(type_unit_pos_cnt[1]), posR = parseInt(type_unit_pos_cnt[2]);
        var gunit = eunit * 10;

        for (var u in positions) {
            if (parseInt(u) < eunit) {
                delete positions[u];
            }
        }
        positions[eunit] = posR;

        var rY = parseInt(thisRect.attr('y'));
        // 显示坐标区间
        var ses = getStartENd4Rect(eunit, posR);
        var widths = svgSettings.width;
        var xt = 0 - widths.chr / 2 - widths.max_bar - widths.gap,
            yt = rY + 60;
        var gTip = d3.select('svg > g.container > g#' + svgSettings.ids.group[gunit]).append('g')
            .attr('class', 'rect-tip')
            .attr('transform', 'translate(' + xt + ', ' + yt + ')');
        gTip.append('rect')
            .attr('x', 0).attr('y', 0)
            .attr('width', 200).attr('height', 50)
            .attr('fill', '#000').attr('stroke', '#fff')
            .attr('fill-opacity', 0.5);
        gTip.append('text')
            .attr('x', 10).attr('y', 10 + 18)
            .attr('fill', '#fff')
            .text(ses.start + '–' + ses.end + ' Kbp');

        for (var unit = eunit; unit >= 1; unit /= 10) {
            d3.select('svg > g.container > g#' + svgSettings.ids.group[unit]).selectAll('*').remove();
        }

        var eunitBp = eunit * 1e3, subEunitBp = eunitBp / 10;
        var data = data4DS[gunit];
        data4DS[eunit] = {}; // eunit => subGunit
        for (var strand in data) {
            if (data[strand][posR]) {
                if (eunit * 1e3 / seqLen > threshold) {
                    data4DS[eunit][strand] = {};
                    $.each(data[strand][posR], function (idx, se) {
                        var p = parseInt(se[0] / subEunitBp);
                        var se1 = [se[0] % subEunitBp, se[1] % subEunitBp];
                        (data4DS[eunit][strand][p]) ? data4DS[eunit][strand][p].push(se1) : data4DS[eunit][strand][p] = [se1];
                    });
                } else {
                    data4DS[eunit][strand] = data[strand][posR];
                }
            }
        }
        if ($.isEmptyObject(data4DS[eunit])) {
            return;
        } else {
            var grp = d3.select('svg > g.container > g#' + svgSettings.ids.group[eunit]);
            if (eunit * 1e3 / seqLen > threshold) {
                chr_and_bars(eunit, grp, data4DS[eunit]);
            } else {
                chr_and_segments(eunit, grp, data4DS[eunit]);
            }
        }
    }

    function mouseout_rect(event) {
        d3.selectAll('#deep-insight-svg > svg .rect-tip').remove();
    }

    function click_rect(event) {
        var threshold = 100; // 序列重复数阈值

        var event = event ? event : (window.event || d3.event);
        var rid = event.id; // rect id

        // 避免重复处理
        if ($('#' + rid).hasClass('clickedRect')) {
            $('#dS-fa').removeClass('minimize');
            $('#minimize-dS-fa').val('Minimize');
            $('#dS-fa').fadeIn();
            return;
        }

        var type_unit_pos_cnt = rid.split('-');
        var rectType = type_unit_pos_cnt[0], eunit = parseInt(type_unit_pos_cnt[1]), posR = parseInt(type_unit_pos_cnt[2]);
        var gunit = eunit * 10;

        if (rectType.match(/plus|minus/)) {
            if (data4DS[gunit][rectType][posR].length <= threshold) {
                show_multiple_seq(gunit, rectType, posR);
                var pid = $('#' + rid).parent().attr('id');
                $('#deep-insight-svg > svg rect').removeClass('clickedRect');
                $('#' + rid).addClass('clickedRect');
            }
        } else {
            $('#dS-fa').hide();
        }
    }

    // 2017.6.25 - 使按坐标顺序输出
    // 但是顺序输出有个问题，有时候会仅部分结果输出。- 此问题已解决
    function show_multiple_seq(gunit, strand, pos) {
        var data = data4DS[gunit][strand][pos];
        strand = (strand === 'minus') ? -1 : 1;
        var eunit = gunit / 10;
        $('#dS-fa').removeClass('minimize');
        $('#minimize-dS-fa').val('Minimize');
        $('#dS-fa > pre').html('');
        var outHtml = [];
        $.each(data, function (iSe, se) {
            var p1 = 0, p2 = 0;
            for (var u = 1e3; u >= eunit; u /= 10) {
                p1 += positions[u] * u * 1e3;
            }
            p2 = p1;
            se[1] = (se[1] > se[0]) ? se[1] : se[1] + eunit * 1e3;
            p1 += se[0], p2 += se[1];
            $.getJSON('/faidx/handle_ajax', {
                species: $('#species').text(), chrName: chr,
                start: p1, end: p2, strand: strand
            }, function (json) {
                if ($.isEmptyObject(json)) {
                    return;
                }
                var lines = json.seq.split("\n");
                outHtml[iSe] = '<span class="fa_header">' + lines.shift().split(' ')[0] + '</span>' + "\n";
                var n = 0;
                $.each(lines, function (iSeg, seg) {
                    if (seg.length === 0) return;

                    var chars = seg.split('');
                    $.each(chars, function (i, nc) {
                        n += 1;
                        outHtml[iSe] += '<span class="dna-' + nc + '" title="' + n + '">' + nc + '</span>';
                    });
                });
                outHtml[iSe] += "\n";
                if (outHtml.length === data.length && noUndefinedValInArray(outHtml)) {
                    if (strand === -1) $('#dS-fa > pre').append("Reverse complement: true.\n\n");
                    $.each(outHtml, function (i, v) {
                        $('#dS-fa > pre').append(v);
                    });
                }
            });
        });
        $('#dS-fa').fadeIn();
    }

    function noUndefinedValInArray(arr) {
        for (var i = 0; i < arr.length; i++) {
            if (typeof arr[i] === 'undefined') {
                return 0;
            }
        }
        return 1;
    }

    // 总长度内不会包含太多片段时，画成线段
    function chr_and_segments(eunit, grp, data) {
        eunit = parseInt(eunit);

        var fontSize = svgSettings.fontSize, colors = svgSettings.colors;
        // 起止，Each
        var txt = grp.append('text').attr('x', 0).attr('y', -30)
            .attr('font-family', svgFontFamily)
            .attr('font-size', fontSize.label)
            .attr('fill', colors.fg).attr('font-weight', 'bold')
            .attr('text-anchor', 'middle');

        var prefix, pf1 = 0, pf2 = 0;
        for (var u = 1e3; u > eunit; u /= 10) {
            pf1 += positions[u] * u;
        }
        pf2 = pf1;
        pf1 += positions[eunit] * eunit;
        pf2 += (positions[eunit] + 1) * eunit;
        prefix = pf1 + '–' + pf2;
        var suffix = 'Kbp';
        txt.append('tspan').attr('x', 0).attr('dy', -fontSize.label).text(prefix + ' ' + suffix);
        txt.append('tspan').attr('x', 0).attr('dy', fontSize.label).text('Each: ' + eunit + ' bp');

        // 首先要画坐标轴
        grp.append('use').attr("xlink:href", "#dS-Axis")
            .attr('x', 20).attr('y', 0);
        grp.append('use').attr("xlink:href", "#dS-Axis")
            .attr('x', 20).attr('y', 0)
            .attr('transform', 'rotate(180 0 500)');
        var gAxisLabels = grp.append('g'); // xt = yt = 0
        var dTexts = [];
        // 主轴
        for (var i = 0; i <= 1e3; i += 100) {
            dTexts.push({
                text: '' + i, x: 0, y: i,
                dy: fontSize.label * 0.35,
                size: fontSize.label,
                anchor: 'middle'
            });
        }

        // plotNs(grp, pf1 * 1e3, pf2 * 1e3, 1);
        plotNs(grp, pf1 * 1e3, pf2 * 1e3, 1 / eunit);

        gAxisLabels.selectAll('text').data(dTexts).enter().append('text')
            .attr('x', function (d) { return d.x }).attr('y', function (d) { return d.y })
            .attr('dy', function (d) { return d.dy })
            .text(function (d) { return d.text })
            .attr('font-family', svgFontFamily).attr('fill', colors.fg)
            .attr('font-size', function (d) { return d.size })
            .attr('text-anchor', function (d) { return d.anchor });
        var plusSegments = grp.append('g').attr('class', 'segments')
            .attr('stroke', '#FF6666').attr('stroke-width', 10);
        var minusSegments = grp.append('g').attr('class', 'segments')
            .attr('stroke', '#99CC66').attr('stroke-width', 10);

        $.each(data, function (strand, ses) {
            $.each(ses, function (idx, se) {
                var s = se[0] / eunit, e = se[1] / eunit;
                e = (e < s) ? (se[1] + eunit * 1e3) / eunit : e;
                if (strand == 'plus') {
                    plusSegments.append('line').attr('id', ['plusSeg', eunit, s, e].join('-'))
                        .attr('x1', 40).attr('y1', s).attr('x2', 40).attr('y2', e)
                        .attr('class', 'clickable')
                        .on('mouseover', mouseover_segment).on('mouseout', function () {
                            $('#dS-tooltip').empty().hide();
                        }).on('click', clickSeg2showSeq)
                        ;
                } else {
                    minusSegments.append('line').attr('id', ['minusSeg', eunit, s, e].join('-'))
                        .attr('x1', -40).attr('y1', s).attr('x2', -40).attr('y2', e)
                        .attr('class', 'clickable')
                        .on('mouseover', mouseover_segment).on('mouseout', function () {
                            $('#dS-tooltip').empty().hide();
                        }).on('click', clickSeg2showSeq)
                        ;
                }
            });
        });
    }

    function plotNs(grp, startPos, endPos, zoomTimes) {
        grp.append('line').attr('stroke-width', 30)
            .attr('x1', 0).attr('y1', 0)
            .attr('x2', 0).attr('y2', 1000).attr('stroke', '#FFCC99')
            .attr('stroke-opacity', 0.5);

        // 不会命名，先随便起吧，就是为了画 N 的分布
        var nSegments = grp.append('g').attr('class', 'segments')
            .attr('stroke-width', 28).attr('stroke', '#000')
            .attr('stroke-opacity', 0.5);
        var dNs = [];
        $.each(data4N, function (idx, se) {
            var s = parseInt(se[0]), e = parseInt(se[1]), y1, y2;
            if (s > endPos) {
                return;
            }
            if (s < startPos && e >= startPos) {
                if (e < endPos) {
                    y2 = (e - startPos) * zoomTimes;
                    dNs.push({ y1: 0, y2: y2, s: s, e: e });
                } else {
                    y2 = 1000;
                    dNs.push({ y1: 0, y2: 1000, s: s, e: e });
                }
            } else if (s >= startPos && s < endPos) {
                y1 = (s - startPos) * zoomTimes;
                if (e < endPos) {
                    y2 = (e - startPos) * zoomTimes;
                    dNs.push({ y1: y1, y2: y2, s: s, e: e });
                } else {
                    y2 = 1000;
                    dNs.push({ y1: y1, y2: 1000, s: s, e: e });
                }
            } else if (s == endPos) {
                dNs.push({ y1: 1000, y2: 1000, s: s, e: e });
            }
        });
        nSegments.selectAll('line').data(dNs).enter().append('line')
            .attr('id', function (d) { return 's-' + d.s + '-e-' + d.e })
            .attr('x1', 0).attr('y1', function (d) { return d.y1 })
            .attr('x2', 0).attr('y2', function (d) { return d.y2 })
            .on('mouseover', mouseover_N_segment)
            .on('mouseout', function () {
                $('#dS-tooltip').empty().hide();
            })
            ;
    }

    function mouseover_N_segment() {
        var event = d3.event;
        var tar = event.srcElement || event.target;
        var lid = tar.id;
        var s_s_e_e = lid.split('-');
        var s = parseInt(s_s_e_e[1]), e = parseInt(s_s_e_e[3]);
        var mousePos = {
            x: event.clientX,
            y: event.clientY
        };
        var xOffset = 20, yOffset = 25, nN = e - s + 1;
        $('#dS-tooltip').show().css({
            'position': 'fixed',
            'top': (mousePos.y - yOffset) + 'px',
            'left': (mousePos.x + xOffset) + 'px'
        }).html('N (unknown or unspecified)<br><br>' + s + '–' + e + '<br><br>' + 'Number of Ns: ' + nN);
    }

    function mouseover_segment(event) {
        var event = event ? event : (window.event || d3.event);
        var ses = getStartENd4Seg(event);
        var mousePos = {
            x: event.clientX,
            y: event.clientY
        };
        var xOffset = 20, yOffset = 25;
        $('#dS-tooltip').show().css({
            'position': 'fixed',
            'top': (mousePos.y - yOffset) + 'px',
            'left': (mousePos.x + xOffset) + 'px'
        }).html(ses.start + '–' + ses.end + ' bp');
    }

    function getStartENd4Seg(event) {
        var tar = event.srcElement || event.target;
        var lid = tar.id;
        var type_unit_s_e = lid.split('-');
        var unit = parseInt(type_unit_s_e[1]), s = parseFloat(type_unit_s_e[2]),
            e = parseFloat(type_unit_s_e[3]);

        var p1 = 0, p2 = 0;
        for (var u = 1e3; u >= unit; u /= 10) {
            p1 += positions[u] * u * 1e3;
        }
        p2 = p1;
        p1 += s * unit, p2 += e * unit;

        var strand = (type_unit_s_e[0].indexOf('plus') == -1) ? -1 : 1;

        return { start: p1, end: p2, strand: strand };
    }

    function getStartENd4Rect(unit, pos) {
        var p1 = 0, p2 = 0;
        for (var u = 1e3; u >= unit; u /= 10) {
            p1 += positions[u] * u;
        }
        p2 = p1 + unit;
        return { start: p1, end: p2 };
    }

    function clickSeg2showSeq(event) {
        var event = event ? event : (window.event || d3.event);
        var ses = getStartENd4Seg(event);

        $('#deep-insight-svg > svg rect').removeClass('clickedRect');

        $.getJSON('/faidx/handle_ajax', {
            species: $('#species').text(), chrName: chr,
            start: ses.start, end: ses.end, strand: ses.strand
        }, function (json) {
            if ($.isEmptyObject(json)) {
                return;
            }
            var lines = json.seq.split("\n");
            $('#dS-fa > pre').html('');
            $('#dS-fa > pre').append('<span class="fa_header">' + lines.shift() + '</span>' + "\n");
            var n = 0;
            $.each(lines, function (idx, seg) {
                if (seg.length === 0) return;

                var chars = seg.split('');
                $.each(chars, function (i, nc) {
                    n += 1;
                    $('#dS-fa > pre').append('<span class="dna-' + nc + '" title="' + n + '">' + nc + '</span>');
                });
                $('#dS-fa > pre').append("\n");
            });
            $('#dS-fa').removeClass('minimize').fadeIn();
            $('#minimize-dS-fa').val('Minimize');
        });
    }
}

$(document).ready(function () {
    $('#minimize-dS-fa').click(function () {
        var value = $('#minimize-dS-fa').val();
        if (value === 'Minimize') {
            $('#dS-fa').addClass('minimize');
            $('#minimize-dS-fa').val('Restore');
        } else {
            $('#dS-fa').removeClass('minimize');
            $('#minimize-dS-fa').val('Minimize');
        }
    });
});